using System.Collections;
using System;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;
using UnityEngine.Networking;

namespace Z1029.PhiPlayer.OpenSource
{
    public class LevelInfo
    {
        const string EncryptChartKey = "0";
        public static LevelInfo currentInfo;

        public string AssetBundlePath;
        public bool LoadFromAssetBundle;
        public string ResourcesPath;
        public bool LoadFromResources;
        public static AssetBundle loadedAssetBundle;
        public TextAsset Chart;
        [NonSerialized]
        public string chart;
        public static AudioClip music;
        public Sprite illustration, illustrationBlur;
        public string musicName, levelInfo;
        public HarderLV levelHarderLv;
        public int levelHarder;
        public string levelMd5;
        public bool EncryptedChart;

        public LevelInfo(string resPath, string musicName, int levelHarder, HarderLV levelHarderLv, bool encryptChart, string levelInfo)
        {
            this.LoadFromResources = true;
            this.ResourcesPath = resPath;
            this.musicName = musicName;
            //this.Chart = chart;
            //this.AssetBundlePath = ABPath;
            //this.levelHarder = chart.GetHashCode();
            this.levelHarderLv = levelHarderLv;
            this.levelHarder = levelHarder;
            this.EncryptedChart = encryptChart;
            this.levelInfo = levelInfo;
            this.LoadFromAssetBundle = false;
            currentInfo = this;
            Start();
        }

        public LevelInfo(string musicName, AudioClip music, TextAsset chart, Sprite illustration, Sprite illustrationBlur, string levelInfo = "Unknown,Unknown", int levelHarder = -1, HarderLV levelHarderLv = HarderLV.SP, bool encryptChart = false)
        {
            this.LoadFromResources = false;
            this.ResourcesPath = null;
            this.musicName = musicName;
            this.Chart = chart;
            LevelInfo.music = music;
            this.illustration = illustration;
            this.illustrationBlur = illustrationBlur;
            //this.AssetBundlePath = ABPath;
            //this.levelHarder = chart.GetHashCode();
            this.levelHarderLv = levelHarderLv;
            this.levelHarder = levelHarder;
            this.EncryptedChart = encryptChart;
            this.levelInfo = levelInfo;
            this.LoadFromAssetBundle = false;
            currentInfo = this;
            Start();
        }

        public Sprite GetSprite(string path)
        {
            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
            byte[] bytes = new byte[fs.Length];
            fs.Read(bytes, 0, (int)fs.Length);
            int width = 512;
            int height = 270;
            Texture2D t2d = new Texture2D(width, height);
            t2d.LoadImage(bytes);
            Sprite sp = Sprite.Create(t2d, new Rect(0, 0, t2d.width, t2d.height), new Vector2(0.5f, 0.5f));
            return sp;
        }



        void Start()
        {
            LevelController.musicPath = null;
            if (LoadFromAssetBundle)
            {
                WWW www = new WWW("File://" + Application.streamingAssetsPath + AssetBundlePath);
                for (; ; )
                {
                    if (www.isDone) break;
                }
                if (www.error != null)
                {
                    Debug.LogError(www.error);
                    return;
                }
                try
                {
                    loadedAssetBundle.Unload(true);
                }
                catch { }
                loadedAssetBundle = AssetBundle.LoadFromMemory(www.bytes);
                music = loadedAssetBundle.LoadAsset<AudioClip>("music");
                illustration = loadedAssetBundle.LoadAsset<Sprite>("Illustration");
                illustrationBlur = loadedAssetBundle.LoadAsset<Sprite>("IllustrationBlur");
                chart = loadedAssetBundle.LoadAsset<TextAsset>("Chart" + "_" + levelHarderLv.ToString()).text;
                www = null;
            }
            else if (LoadFromResources)
            {
#if !UNITY_EDITOR
            try
            {
#endif
                //Resources.UnloadUnusedAssets();
                //music = Resources.Load<AudioClip>(ResourcesPath + "/music");
                //Chart = Resources.Load<TextAsset>(ResourcesPath + "/Chart_" + levelHarderLv.ToString());
                //illustration = Resources.Load<Sprite>(ResourcesPath + "/Illustration");
                //illustrationBlur = Resources.Load<Sprite>(ResourcesPath + "/IllustrationBlur");
                string chartPath = (new DirectoryInfo(ResourcesPath)).GetFiles()[0].FullName;

                foreach (FileInfo fi in (new DirectoryInfo(ResourcesPath)).GetFiles())
                {
                    string fullName = fi.FullName.Trim();
                    if (fi.Name.Contains(levelHarderLv.ToString()))
                    {
                        chartPath = fullName;
                        chart = File.ReadAllText(fullName, Encoding.UTF8);
                        Debug.Log("Find chart file : " + fullName);
                        break;
                    }
                }
                if (chart != "" && chart != null)
                    goto LoadChart;
                foreach (FileInfo fi in (new DirectoryInfo(ResourcesPath)).GetFiles())
                {
                    string fullName = fi.FullName.Trim();
                    if (fullName.EndsWith(".ppc"))
                    {
                        chartPath = fullName;
                        chart = File.ReadAllText(fullName, Encoding.UTF8);
                        if (!fullName.Contains(levelHarderLv.ToString()))
                        {
                            this.levelHarderLv = HarderLV.SP;
                            this.levelHarder = -1;
                        }
                        Debug.Log("Find chart file : " + fullName);
                        break;
                    }
                    else if (fullName.EndsWith(".txt") || fullName.EndsWith(".json") || fullName.EndsWith(".bytes") || fullName.EndsWith(".pec"))
                    {
                        chartPath = fullName;
                        chart = File.ReadAllText(fullName, Encoding.UTF8);
                        if (!fullName.Contains(levelHarderLv.ToString()))
                        {
                            this.levelHarderLv = HarderLV.SP;
                            this.levelHarder = -1;
                        }
                        Debug.Log("Find chart file : " + fullName);
                        break;
                    }
                }

            LoadChart:
                Chart gameChart = null;
#if !UNITY_EDITOR
                try
                {
#endif
                if (chart.Contains("alphaEvents"))
                {
                    //Z1029 Format chart
                    gameChart = null;
                }
                else if (chart.StartsWith("BinaryChartPath:"))
                {
                    gameChart = null;
                }
                else if (chart.Contains("judgeLineDisappearEvents"))
                {
                    gameChart = PhigrosChartReader.ReadChart(chart);
                }
                else if (chart.Contains("bp") && chart.Contains("#") && chart.Contains("&"))
                {
                    gameChart = PECChartReader.ReadChart(chart);
                    Utils.AndroidToastStringShow("The \".pec\" file is not fully support.");
                }
                else
                {
                    Utils.AndroidToastStringShow("Loaded chart is not in a correct format.");
                    Application.LoadLevel(0);
                }
#if !UNITY_EDITOR
                }
                catch (Exception ex)
                {
                    Utils.AndroidToastStringShow("Chart read error : " + ex.Message);
                    Application.LoadLevel(0);
                }
#endif
                if (gameChart != null)
                {
                    if (gameChart.chartVersion == "PEC")
                    {
                        //string file = JsonUtility.ToJson(gameChart, false);
                        //File.Move(chartPath, chartPath + ".bak");
                        //string newChartPath = ResourcesPath + "/" + Path.GetFileName(chartPath).Split('.')[0] + ".bin";
                        //string linkChartPath = ResourcesPath + "/" + Path.GetFileName(chartPath).Split('.')[0] + ".ppc";
                        //FileStream fs = new FileStream(newChartPath, FileMode.Create, FileAccess.Write);
                        //BinaryFormatter bf = new BinaryFormatter();
                        //bf.Serialize(fs, gameChart);
                        //fs.Close();
                        //chart = "BinaryChartPath:" + newChartPath;
                        //File.WriteAllText(linkChartPath, chart, Encoding.UTF8);
                    }
                    //else chart = JsonUtility.ToJson(gameChart);
                    //
                }

                if (File.Exists(ResourcesPath + "//Illustration.png"))
                {
                    illustration = GetSprite(ResourcesPath + "//Illustration.png");
                    illustrationBlur = GetSprite(ResourcesPath + "//IllustrationBlur.png");
                }
                else
                {
                    foreach (FileInfo fi in (new DirectoryInfo(ResourcesPath)).GetFiles())
                    {
                        string fullName = fi.FullName.Trim();
                        if (fullName.EndsWith(".png") || fullName.EndsWith(".jpg") || fullName.EndsWith(".jpeg") || fullName.EndsWith(".bmp"))
                        {
                            illustration = GetSprite(fullName);
                            illustrationBlur = GetSprite(fullName);
                            break;
                        }
                    }
                }

#if !UNITY_EDITOR
            }
            catch (Exception e)
            {
                Utils.AndroidToastStringShow(e.Message);
            }
#endif
            }
            else
            {

                chart = Chart.text;

                Chart gameChart;
                if (chart.Contains("alphaEvents"))
                {
                    //Z1029 Format chart
                    gameChart = null;
                }
                else if (chart.Contains("judgeLineDisappearEvents"))
                {
                    gameChart = PhigrosChartReader.ReadChart(chart);
                }
                else if (chart.Contains("bp") && chart.Contains("#") && chart.Contains("&"))
                {
                    gameChart = PECChartReader.ReadChart(chart);
                    Utils.AndroidToastStringShow("The \".pec\" file is not fully support.");
                }
                else gameChart = null;
                //if (gameChart != null)
                //    chart = JsonUtility.ToJson(gameChart);
            }

            levelMd5 = SecurityUtils.Md5Sum(chart);
            UnityEngine.SceneManagement.SceneManager.LoadSceneAsync("GamePlay");
        }

        public enum HarderLV
        {
            EZ, HD, IN, AT, SP
        }
    }
}